/**************************************
          editcontig
routines from new.c and hozdisp2.c that may still be used.
******************************************/
#include "../clam/clam.h"
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include "fpp.h"
#include "dirent.h"
#include <gtk/gtkwidget.h>
#ifdef ALPHA
#include <sex.h>
#endif

extern int centreMarker, centreClone;
extern GtkWidget *ctg_window;
extern void refresh_gtk_ctgdisplay();
extern void refresh_all_track_colors();

void hiddenToggle(), hidePseudo(), hideBuried(), hideNone();

BOOL fppInsert(Array a, char *s, int *index, BOOL (*order)());
BOOL fppFind(Array a, char *s, int *ip, BOOL (* order)());
BOOL cloneOrder(void *s, void *b);
void recalcparents(void);
void markersetzero(void);
void ordermerged(int count);

void setmarkerposctg(void);
void sortmarkers(void);

int centreMarker=-1, centreClone=-1; 

void fingerprinthigh(), gelprinthigh();

void selectOptions(void);
void selectOptions2(void);
void flipselected();
void snapselectedleft(void);
void snapselectedright(void);
void snaphighleft(void);
void snaphighright(void);
void resizehighleft(void);
void resizehighright(void);
void selectedmove(void);
void recalcorder(void);
void keysetselect(void);

/*********************************************************
           DEF: selectclear
Select Option - Clear
**********************************************************/
void selectclear()
{
  struct contig *p;
  BOOL last;
  CLONE *clone;

  p=root;
  last = FALSE;
  
  if(ctg_window==NULL)
    return;
  while(!last){  
    clone = arrp(acedata,p->next,CLONE);
    clone->selected = FALSE;
    if(p->new==NULL)
      last = TRUE;
    p = p->new;
  } 
  if(graphActivate(g3))
    drawfpdata(0);

  refresh_gtk_ctgdisplay();  /*fred 4/1/03*/
}

/*********************************************************
           DEF: stselect
Select Option - Pick
**********************************************************/
void stselect()
{
  fpflag = ~fpflag;
  if(fpflag)
    graphBoxDraw(fpflagbox,BLACK,RED);
  else
    graphBoxDraw(fpflagbox,BLACK,WHITE);
  if(geladd){
    geladd=FALSE;
    if(graphActivate(gtest))
      graphBoxDraw(geladdbox,BLACK,WHITE);
  }
  if(fpadd){
    if(graphActivate(g3))
      graphBoxDraw(fpaddbox,BLACK,WHITE);
    fpadd= FALSE;
  }    
}

/*********************************************************
           DEF: fpsequenced
Select Option - Sequenced
**********************************************************/
void fpsequenced()
/* go through each clone in ctg until all that are sequenced are added */
{
  struct contig *p;
  BOOL last;
  CLONE *clone;

  p=root;
  last = FALSE;

  if(ctg_window==NULL)
    return;
  while(!last){                             
    clone = arrp(acedata,p->next,CLONE);
    if(clone->seqstat != 0){
      clone->selected = TRUE;
    }
    if(p->new==NULL)
      last = TRUE;
    p = p->new;
  } 
  refresh_all_track_colors();  /*fred 4/1/03*/
}

/*********************************************************
           DEF: selectquit
Select Option - Quit
**********************************************************/
void selectquit()
{
  if (graphActivate(gselected))
  {
     fpflag = FALSE;
     graphDestroy();
  }
}

/*********************************************************
           DEF: selectquit2
Select Option - Quit
**********************************************************/
void selectquit2()
{
  if (graphActivate(gselected2))
  {
     graphDestroy();
  }
}

/*********************************************************
           DEF: recalculorder
Select Option - Recalc
also is called by drawfpdata and trace.
**********************************************************/
void recalculorder()
{
  if(!merging){
    if(ctg_window==NULL)
      return; 
    orderclones(currentctg);
    ctgdisplay(currentctg);
  }
  else
   recalcorder();
}

/*********************************************************
           DEF: selectOptions
Select Options menu
**********************************************************/
void selectOptions()
{
  float line;
  static MENUOPT quitmenu[] = {
  { (VoidRoutine)selectquit, "Close"},
  { graphPrint, "Print Screen"},
  { 0, 0 }};

  if(graphActivate(gselected)){
    graphClear();
    graphPop();
  }
  else{
    gselected = graphCreate (TEXT_FIT,"Select Clones",.2,.2,.32,.18) ;
    graphMenu (quitmenu) ;
  }
  line = 1.0;
  graphText("Select:",2.0,line);
  line += 1.5;
  if(!fpflag)
    fpflagbox = graphButton("Pick",stselect,4.0,line);
  else{
    fpflagbox = graphButton("Pick",stselect,4.0,line);
    graphBoxDraw(fpflagbox,BLACK,RED);
  }
  graphButton("Region",fpRegion,10.0,line);
  graphButton("Clear",selectclear,18.0,line);
  line +=2.0;
  graphButton("Contig",fpContig,4.0,line);
  graphButton("Sequenced",fpsequenced,12.0,line);
  graphButton("Keyset",keysetselect,23.0,line);

  line +=2.0;
  graphText("Operation on Selected:",2.0,line);
  line += 1.5;
  graphButton("Fingerprint",fingerprinthigh,4.0,line);
  graphButton("Gels",gelprinthigh,17.0,line);
  graphButton("Move/Remove",selectedmove,23.0,line);
  line +=2.0;
  graphButton("Close",selectquit,17.0,line);
  graphRedraw();
}

void selectOptions2()
{
  float line;
  static MENUOPT quitmenu[] = {
  { (VoidRoutine)selectquit2, "Close"},
  { graphPrint, "Print Screen"},
  { 0, 0 }};

  if(graphActivate(gselected2)){
    graphClear();
    graphPop();
  }
  else{
    gselected2 = graphCreate (TEXT_FIT,"Edit Clones",.2,.2,.38,.23) ;
    graphMenu (quitmenu) ;
  }
  line = 1.0;
  graphText("Operation on Selected:",2.0,line);
  line += 1.5;
  graphButton("Snap Left End",snapselectedleft,4.0,line);
  graphButton("Snap Right End",snapselectedright,19.0,line);
  graphButton("Flip",flipselected,35.0,line);

  line +=2.0;
  graphText("Operation on Highlighted:",2.0,line);
  line +=1.5;
  graphButton("Snap Left End",snaphighleft,4.0,line);
  graphButton("Snap Right End",snaphighright,19.0,line);
  line +=2.0;
  graphButton("Stretch Left End",resizehighleft,4.0,line);
  graphButton("Stretch Right End",resizehighright,22.0,line);

  line +=2.0;
  graphText("Operation on contig:",2.0,line);
  line +=1.5;
  graphButton("Recalc Order",recalculorder,4.0,line);
  line +=2.0;
  graphButton("Close",selectquit2,17.0,line);
  graphRedraw();
}

void delmerge()
{
  mergecontig1 = mergecontig2 = 0;
  merging = FALSE;
}

void recalcparents()
{
 int i;
 int index;
 CLONE *clone;

  for(i=0;i<arrayMax(acedata);i++){
    clone = arrp(acedata,i,CLONE);
    if(clone->match[0] != ' '){
      if(!fppFind(acedata,clone->match,&index, cloneOrder)) {
	printf("ERROR could not find clone %s\n",clone->match);
      }
      else{
	clone->parent = index;
      }
    }
  }
}
void markersetzero()
{
  int i;
  CLONE *clone;
  struct markerclone *newmarker;
  struct markertop *markertop;
  struct marker *marker;
  int index;

  for(i=0;i<arrayMax(acedata);i++){
    clone = arrp(acedata,i,CLONE);    
    markertop = clone->marker;
    while(markertop != NULL){
      if(fppFind(markerdata,markertop->marker,&index, markerOrder)){
        markertop->markerindex = index;
        marker = arrp(markerdata,markertop->markerindex,MARKER);
        marker->cloneindex = -1;
        newmarker=marker->nextclone;
        while(newmarker != NULL){
          newmarker->cloneindex = -1;
          newmarker = newmarker->nextclone;
        }
      }
      else{
	printf("YOOOO %s not found\n",markertop->marker);
	marker = arrp(markerdata,markertop->markerindex,MARKER);
	marker->cloneindex = -1;
      }
      markertop = markertop->nextmarker;
    }
  }
}
  
void flipcontig(int ctg)
{
  int addbit,temp;
  CLONE *clone;
  int i;
  struct markerctgpos *pos;
  BOOL okay = TRUE;

  if(contigs[ctg].left<0)
    addbit = contigs[ctg].left;
  else
    addbit = contigs[ctg].left;
  
  clone = arrp(acedata,contigs[ctg].start,CLONE);
  while(okay){
    clone->x -= addbit;
    clone->x = -clone->x;
    clone->x += (addbit+(contigs[ctg].right-contigs[ctg].left));
    clone->y -= addbit;
    clone->y = - clone->y;
    clone->y += (addbit+(contigs[ctg].right-contigs[ctg].left));
    temp = clone->x;
    clone->x = clone->y;
    clone->y = temp;
    if(clone->next >=0)
       clone = arrp(acedata,clone->next,CLONE);
    else
      okay = FALSE;
  }
  /*Yo flip the markers aswell */
  for(i=0;i<arrayMax(markerdata);i++){
    pos = arrp(markerdata,i,MARKER)->pos;
    while(pos!=NULL){
      if(pos->ctg == ctg){
	pos->pos -= addbit;
	pos->pos = -pos->pos;
	pos->pos += (addbit+(contigs[ctg].right-contigs[ctg].left));
      }
      pos= pos->next;
    }
  }
  if(!merging){
    setmarkerposctg();
    sortmarkers();
    orderclones(ctg);
    ctgdisplay(ctg);
  }
}

int sortctg2(const void* orig_a, const void *orig_b)
{
  int x1, x2;

  struct contig *a;
  struct contig *b;

  a = (struct contig *)orig_a;
  b = (struct contig *)orig_b;

  x1 = arr(acedata, a->next, CLONE).x;
  if(arr(acedata,a->next,CLONE).ctg == mergecontig2)
    x1 += (contigs[mergecontig1].right - contigs[mergecontig2].left) + startpt;
  x2 = arr(acedata, b->next, CLONE).x;
  if(arr(acedata,b->next,CLONE).ctg == mergecontig2)
    x2 +=  (contigs[mergecontig1].right - contigs[mergecontig2].left) + startpt;
  if (x1 < x2) return -1;
  if (x1 > x2) return 1;
  return 0;
}

void ordermerged(int count)
{
  int i;
  struct contig *p1;
  int index=-1;

  if(clhigh != NULL)
    index = clhigh->next;
  qsort(root, count, sizeof(struct contig), sortctg2);
  for(i=0;i<count-1;i++) root[i].new = &(root[i+1]);
  root[i].new = NULL;
  if(index != -1){
    p1 = root;
    while(p1!=NULL){
      if(p1->next == index){
        clhigh = p1;
      }
      p1 = p1->new;
    }
  }
}

void recalcorder()
{
  ordermerged(contigs[mergecontig1].count+contigs[mergecontig2].count);
  ctgdisplay(0);
}
